<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
	<title>图片加载/压缩/下载</title>

  <script type="text/javascript" src="./jszip.js"></script>
  <script type="text/javascript" src="./FileSaver.js"></script>
  <script type="text/javascript" src="./jquery.js"></script>

	<style type="text/css" media="screen">
	#dropTarget2 {  float: left;
		width: 200px;
		height: 200px;
		background: #eee;
		border: 1px dashed #999;
		-webkit-box-align: center;
		-webkit-box-pack: center;
		display: -webkit-box;
	}
  #output{ font-size:11px;  clear: both;   padding-top: 5px;}
  #output div{width: 140px; height: 240px; float: left;  margin: 10px;}
  #output div img{width:100%;}
  #output div p{margin-top: 2px}

	</style>

</head>
<body>
  <button style="display: none" onclick='showAll()'>显示全部</button>
  <button onclick='zipAndDown()'>下载压缩包</button>

	<div id="dropTarget2">图片文件（夹）拖放到这</div>

	<div id="output">
   <hr> 
  </div>

<script type="text/javascript">

var glbFiles =[]; //用来存储加载的文件引用，记得在必要的时候清空
var glbZip = new JSZip();


var dropTargetEle2 = document.getElementById("dropTarget2");

// 监听drag drop事件
dropTargetEle2.addEventListener("dragenter", handleIt, false);
dropTargetEle2.addEventListener("dragover", handleIt, false);
dropTargetEle2.addEventListener("drop", handleIt, false);


//压缩一张图片到压缩包中,压完回调一个函数
function zipImg(zipObj,file,callback){
  var reader = new FileReader();
  reader.readAsDataURL(file)
  reader.onloadend = function(event){
    var imgData = event.target.result.split(',').pop();
    var fname = ''+Date.parse(new Date())+file.name;
    zipObj.file(fname, imgData, {base64: true});
    callback();
  }
}

function zipDealOne(loopFiles,callback){
  if(loopFiles.length==0){
    callback();
    return;

  }else{
    var curFile = loopFiles.shift();

    if(curFile.type==="image/jpeg") {
      zipImg(  glbZip, curFile ,  function(){
        zipDealOne(loopFiles,callback); //递归
      });
    }else{
      zipDealOne(loopFiles,callback); //递归
    }

  }

}

function zipAndDown(){
  if(glbFiles.length===0){
    console.log('没有图片！');
    return;
  }
  var loopFiles = arrClone(glbFiles);
  zipDealOne(loopFiles,function(){
    console.warn('处理完毕！999');
    glbZip.file('README.md','这是说明文件');
    glbZip.generateAsync({type:"blob"}).then(function (blob) {
      saveAs(blob, "图片导出.zip");
    }, function (err) {
        console.warn( 'err 0x33948 '+err.toString() );
    });
  });
  return;

}




// 拖放图片文件夹处理函数
function handleIt(event) {
  event.preventDefault(); 
  var items = event.dataTransfer.items;
  for (var i=0; i<items.length; i++) {
    // webkitGetAsEntry is where the magic happens
    var item = items[i].webkitGetAsEntry();
    console.log(item);
    glbItem = item;
    if (item) {
      traverseFileTree(item);
    }
  }
}

// 递归遍历拖放上来的文件,由于createReader  readEntries的特殊性（每次调用只能返回100条，所以又加一个递归）
// 这里的代码慢慢琢磨
function traverseFileTree(item, path) {
  path = path || "";

  if (item.isFile) {
    item.file(function(file) {
      //console.log("File:", path + file.name);
      glbFiles.push(file); // 文件对象推入全局数组，以便随时使用
      showImg(file);
    });

  } else if (item.isDirectory) {
    var dirReader = item.createReader();
    var allEntries = [];
    
    var funGetEnt = function(){
      dirReader.readEntries(function(entries) {
        if(entries.length!==0){ //不为空就压入，且继续递归
          for (var i=0; i<entries.length; i++) {
            allEntries.push(entries[i]);
          }
          funGetEnt();
        }else{
          //console.log('done '+allEntries.length);
          for (var i=0; i<allEntries.length; i++) {
            traverseFileTree(allEntries[i], path + item.name + "/"); //递归调用
          }
        }
      });
    };
    
    funGetEnt();

  }
}


/** 
 * 以下代码演示了如何从glbFiles中获取并显示图片
 *
*/

// 输出单张图片
function showImg(oneFile){

  if(oneFile.type!=="image/jpeg") {
    console.warn('这不是jpeg图片');
    return ;
  }

  var reader = new FileReader(); //

  oneFile && reader.readAsDataURL(oneFile);//// 以DataUrl的方式获取文件  这个时候实际上是把数据读到了reader.result中
  //var url = reader.result; //这种直接用法是错的，疑问readAsDataURL是异步，应该用回调的方式
  reader.onloadend = function(event){
    var url = event.target.result;

    var div = document.createElement("div");

    var img = document.createElement("img");
    img.src = url;
    div.appendChild( img );

    var txt = document.createElement("p");
    txt.innerText = oneFile.name;
    div.appendChild( txt );

    document.getElementById("output").appendChild( div );

  };

}

// 显示所有图片，调试用
function showAll(){
  !glbFiles.length && console.log('无图片');
  for(var a in glbFiles){
    showImg(glbFiles[a])
  }
}




// 克隆对象
function objClone(oldObj){
    var newObj = $.extend(true, {}, oldObj);
    return newObj;
}

function arrClone(oldArr){
  var newArr=[];
  $.each(oldArr,function(i,n){
    newArr.push(n);
  });
  return newArr;
}



/**

## 部分代码参考来源：

 - h5上传文件夹中的内容： http://stackoverflow.com/questions/3590058/does-html5-allow-drag-drop-upload-of-folders-or-a-folder-tree


  //var img = document.createElement("img");
  //img.src = txt;
  //document.getElementById("result").appendChild( img );


*/
</script>

</body>
</html>